/**
 * Element Plus组件修复工具
 * @author Wu.Liang
 * @date 2025-01-30
 */

import { nextTick, ref, onMounted, onUnmounted } from 'vue'

/**
 * 修复Element Plus组件的getBoundingClientRect错误
 */
export function fixElementPlusGetBoundingClientRect() {
  // 重写Element Plus内部的getBoundingClientRect调用
  const originalGetBoundingClientRect = Element.prototype.getBoundingClientRect
  
  Element.prototype.getBoundingClientRect = function() {
    try {
      // 检查元素是否存在且在DOM中
      if (!this || !document.contains(this)) {
        console.warn('Element Plus: 元素不存在或不在DOM中，返回默认值')
        return {
          x: 0,
          y: 0,
          width: 0,
          height: 0,
          top: 0,
          right: 0,
          bottom: 0,
          left: 0,
          toJSON: () => ({ x: 0, y: 0, width: 0, height: 0, top: 0, right: 0, bottom: 0, left: 0 })
        } as DOMRect
      }
      
      // 检查元素是否可见
      const style = window.getComputedStyle(this)
      if (style.display === 'none' || style.visibility === 'hidden') {
        console.warn('Element Plus: 元素不可见，返回默认值')
        return {
          x: 0,
          y: 0,
          width: 0,
          height: 0,
          top: 0,
          right: 0,
          bottom: 0,
          left: 0,
          toJSON: () => ({ x: 0, y: 0, width: 0, height: 0, top: 0, right: 0, bottom: 0, left: 0 })
        } as DOMRect
      }
      
      // 调用原始方法
      return originalGetBoundingClientRect.call(this)
    } catch (error) {
      console.warn('Element Plus: getBoundingClientRect调用失败，返回默认值:', error)
      return {
        x: 0,
        y: 0,
        width: 0,
        height: 0,
        top: 0,
        right: 0,
        bottom: 0,
        left: 0,
        toJSON: () => ({ x: 0, y: 0, width: 0, height: 0, top: 0, right: 0, bottom: 0, left: 0 })
      } as DOMRect
    }
  }
}

/**
 * 安全的Element Plus组件包装器
 */
export function createSafeElementPlusWrapper() {
  return {
    name: 'SafeElementPlusWrapper',
    setup() {
      const isReady = ref(false)
      
      const initComponent = async () => {
        try {
          await nextTick()
          // 等待一个渲染周期
          await new Promise(resolve => setTimeout(resolve, 50))
          isReady.value = true
        } catch (error) {
          console.warn('SafeElementPlusWrapper: 初始化失败:', error)
        }
      }
      
      onMounted(() => {
        initComponent()
      })
      
      onUnmounted(() => {
        isReady.value = false
      })
      
      return {
        isReady
      }
    }
  }
}

/**
 * 延迟初始化Element Plus组件
 */
export function delayElementPlusInit(component: any, delay: number = 100) {
  return new Promise((resolve) => {
    setTimeout(() => {
      try {
        if (component && typeof component.init === 'function') {
          component.init()
        }
        resolve(true)
      } catch (error) {
        console.warn('延迟初始化Element Plus组件失败:', error)
        resolve(false)
      }
    }, delay)
  })
}

/**
 * 修复Element Plus下拉菜单的定位问题
 */
export function fixDropdownPositioning() {
  // 监听所有el-dropdown组件
  const observer = new MutationObserver((mutations) => {
    mutations.forEach((mutation) => {
      mutation.addedNodes.forEach((node) => {
        if (node.nodeType === Node.ELEMENT_NODE) {
          const element = node as Element
          if (element.classList.contains('el-dropdown')) {
            fixDropdownElement(element)
          }
        }
      })
    })
  })
  
  observer.observe(document.body, {
    childList: true,
    subtree: true
  })
  
  return observer
}

/**
 * 修复单个下拉菜单元素
 */
function fixDropdownElement(element: Element) {
  try {
    // 延迟执行定位计算
    setTimeout(() => {
      const dropdownMenu = element.querySelector('.el-dropdown-menu')
      if (dropdownMenu) {
        // 重新计算位置
        const rect = element.getBoundingClientRect()
        if (rect.width > 0 && rect.height > 0) {
          // 触发重新定位
          const event = new Event('resize')
          window.dispatchEvent(event)
        }
      }
    }, 50)
  } catch (error) {
    console.warn('修复下拉菜单定位失败:', error)
  }
}

/**
 * 修复Element Plus工具提示的定位问题
 */
export function fixTooltipPositioning() {
  // 监听所有el-tooltip组件
  const observer = new MutationObserver((mutations) => {
    mutations.forEach((mutation) => {
      mutation.addedNodes.forEach((node) => {
        if (node.nodeType === Node.ELEMENT_NODE) {
          const element = node as Element
          if (element.classList.contains('el-tooltip')) {
            fixTooltipElement(element)
          }
        }
      })
    })
  })
  
  observer.observe(document.body, {
    childList: true,
    subtree: true
  })
  
  return observer
}

/**
 * 修复单个工具提示元素
 */
function fixTooltipElement(element: Element) {
  try {
    // 延迟执行定位计算
    setTimeout(() => {
      const tooltipContent = element.querySelector('.el-tooltip__content')
      if (tooltipContent) {
        // 重新计算位置
        const rect = element.getBoundingClientRect()
        if (rect.width > 0 && rect.height > 0) {
          // 触发重新定位
          const event = new Event('resize')
          window.dispatchEvent(event)
        }
      }
    }, 50)
  } catch (error) {
    console.warn('修复工具提示定位失败:', error)
  }
}

/**
 * 初始化所有Element Plus修复
 */
export function initElementPlusFixes() {
  console.log('初始化Element Plus修复...')
  
  // 修复getBoundingClientRect
  fixElementPlusGetBoundingClientRect()
  
  // 修复下拉菜单定位
  const dropdownObserver = fixDropdownPositioning()
  
  // 修复工具提示定位
  const tooltipObserver = fixTooltipPositioning()
  
  // 返回清理函数
  return () => {
    dropdownObserver.disconnect()
    tooltipObserver.disconnect()
  }
} 